package com.pie4cloud.pie.dmz.util;

import com.pie4cloud.pie.dmz.entty.constant.ConstantValue;
import org.apache.commons.io.FileUtils;

import java.io.*;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class FileUtil {

	private static final String suffix = "part";

	public static void splintFile(File file, int blockSize, String outDirPath) throws IOException {
		if (!file.exists()) {
			throw new FileNotFoundException(file.getPath());
		}
		if (!new File(outDirPath).exists())
			new File(outDirPath).mkdirs();
		String fileName = file.getName();

		long size = blockSize * 1024 * 1024;//MB字节
		long length = file.length();
		int count = (int) (length % size == 0 ? length / size : length / size + 1);

		int countLen = String.valueOf(count).length();
		FileInputStream fileInputStream = new FileInputStream(file);
		final FileChannel channelSource = fileInputStream.getChannel();
		FileChannel channel = null;
		FileOutputStream fileOutputStream = null;
		boolean result = false;
		for (int i = 1; i <= count; i++) {
			try {
				File filePart = new File(outDirPath, fileName + "." + String.format("%0" + countLen + "d", i) + "." + suffix);
				fileOutputStream = new FileOutputStream(filePart);
				channel = fileOutputStream.getChannel();
				channelSource.transferTo((i - 1) * size, i != count ? size : length - (i - 1 * size), channel);
				fileOutputStream.close();
			} catch (IOException e) {
				result = true;
				throw e;
			} finally {
				if (fileOutputStream != null)
					fileOutputStream.close();
				if (channel != null)
					channel.close();
			}
		}
		try {

		} finally {
			try {
				if (fileInputStream != null)
					fileInputStream.close();
				if (channelSource != null)
					channelSource.close();
				if (result) {
					FileUtils.deleteDirectory(new File(outDirPath));
				}
			} catch (IOException e) {

			}
		}
	}


	public static void mergeFile(String sourtPath, String targetPath) throws IOException {
		File fileDirSource = new File(sourtPath);
		File fileDirTarget = new File(targetPath);
		if (fileDirSource.exists() && fileDirSource.isDirectory()) {
			if (!fileDirTarget.exists())
				fileDirTarget.mkdirs();
			File[] listFiles = fileDirSource.listFiles(f -> f.getName().endsWith(suffix));
			int length = listFiles.length;
			String suffixName = "." + String.format("%0" + String.valueOf(String.valueOf(length).length()) + "d", 1) + "." + suffix;
			String fileName = listFiles[0].getName().replaceAll(suffixName, "");
			File file = new File(targetPath, fileName);
			FileChannel channelOut = new FileOutputStream(file).getChannel();

			if (length > 0) {
				FileChannel channel;
				long start = 0;
				for (int i = 0; i < length; i++) {
					File filePart = listFiles[i];
					channel = new FileInputStream(filePart).getChannel();
					channelOut.transferFrom(channel, start, filePart.length());
					start += filePart.length();
					channel.close();
				}

				try {

				} finally {
					channelOut.close();
				}
			}

		}
	}


	public static void mergeDirFile(String sourtPath, String targetPath) throws IOException {
		File fileDirSource = new File(sourtPath);
		File fileDirTarget = new File(targetPath);
		if (fileDirSource.exists() && fileDirSource.isDirectory()) {
			if (!fileDirTarget.exists())
				fileDirTarget.mkdirs();
			File[] listFiles = fileDirSource.listFiles();
			List<File> list = Arrays.asList(listFiles);
			list.sort(new Comparator<File>() {
				@Override
				public int compare(File o1, File o2) {
					return Integer.valueOf(o1.getName()) - Integer.valueOf(o2.getName());
				}
			});

			int length = listFiles.length;//文件夹个数
			String suffixName = "." + String.format("%0" + String.valueOf(String.valueOf(length).length()) + "d", 1) + "." + suffix;
			String fileName = list.get(0).listFiles()[0].getName().replaceAll(suffixName, "");
			File file = new File(targetPath, fileName);
			FileChannel channelOut = new FileOutputStream(file).getChannel();
			if (length > 0) {
				FileChannel channel;
				long start = 0;
				for (int i = 0; i < length; i++) {
					File filePart = list.get(i).listFiles()[0];
					channel = new FileInputStream(filePart).getChannel();
					channelOut.transferFrom(channel, start, filePart.length());
					start += filePart.length();
					channel.close();
				}

				try {

				} finally {
					channelOut.close();
				}
			}
			FileUtils.deleteDirectory(fileDirSource);

		}
	}


	public static void main(String[] args) {
		try {
			String fileName = "新建文件夹.rar";
			String md5FileName = "9d65160aa26fe25aabe2c3184d9acd44";
			File localFile = new File(ConstantValue.DOWNLOAD_FILE_PATH + md5FileName, fileName);

			FileUtil.mergeDirFile(ConstantValue.DOWNLOAD_FILE_BLOCK_PATH + md5FileName, localFile.getParent());


//            String outPath = "E:\\开发环境安装包\\1";
//            splintFile(new File("E:\\迅雷下载\\cn_windows_7_ultimate_x64_dvd_x15-66043.iso"), 20, outPath);
//            mergeFile(outPath, "E:\\开发环境安装包\\2");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
